using System;
using System.Data;
using System.Drawing;
using Habanero.Base;
using Habanero.BO;
using Habanero.BO.ClassDefinition;
using Habanero.Faces.Base;
using Habanero.Faces.Win;
using FireStarterModeller.BO;

namespace FireStarterModeller.UI
{
    /// <summary>
    /// The GridBOEditorControl for Editing <see cref="DMRelationshipProperty"/>. This is used by
    /// <see cref="DMRelationshipsControl"/>
    /// </summary>
    public class DMRelatedPropertiesControl : UserControlWin, IFormControl, IBusinessObjectControl
    {
        private DMRelationship _dmRelationship;

        public IGridControl SelectorAndBOEditorControl { get; private set; }

        public DMRelatedPropertiesControl(IControlFactory controlFactory)
        {
            if (controlFactory == null) throw new ArgumentNullException("controlFactory");
            IGroupBox groupBox = controlFactory.CreateGroupBox("Relationship Properties");
            SelectorAndBOEditorControl = controlFactory.CreateEditableGridControl();
            SelectorAndBOEditorControl.Buttons["Save"].Visible = false;
//            SelectorAndBOEditorControl.Dock = DockStyle.Fill;
            groupBox.Controls.Add(SelectorAndBOEditorControl);
            groupBox.Width = 360;
            SelectorAndBOEditorControl.Top = 15;
            SelectorAndBOEditorControl.Left = 5;
            SelectorAndBOEditorControl.Width = 340;
            SelectorAndBOEditorControl.FilterControl.Visible = false;
            BorderLayoutManager layoutManager = controlFactory.CreateBorderLayoutManager(this);
            layoutManager.AddControl(groupBox, BorderLayoutManager.Position.Centre);
            this.MinimumSize = new Size(groupBox.Width, 100);
            UpdateState();
        }

        /// <summary>
        /// The <see cref="DMRelationship"/> whose <see cref="DMRelationshipProperty"/> is being shown in this control
        /// </summary>
        public DMRelationship Relationship
        {
            set
            {
                try
                {
                    if (_dmRelationship != null && _dmRelationship.ReverseRelationship != null) _dmRelationship.ReverseRelationship.Props["ClassID"].Updated -= ReverseRelationship_OnClassPropertyUpdated;
                    _dmRelationship = value;
                    if (_dmRelationship != null && _dmRelationship.ReverseRelationship != null) _dmRelationship.ReverseRelationship.Props["ClassID"].Updated += ReverseRelationship_OnClassPropertyUpdated;

                    BusinessObjectCollection<DMRelationshipProperty> col;
                    if (_dmRelationship != null)
                    {
                        col = _dmRelationship.RelationshipProperties;
                    }
                    else
                    {
                        col = new BusinessObjectCollection<DMRelationshipProperty>();
                    }
                    SelectorAndBOEditorControl.BusinessObjectCollection = col;

                    SetupOwnerPropertyColumn();
                    SetupRelatedPropertyColumn();

                    UpdateState();
                }
                catch (Exception ex)
                {
                    GlobalRegistry.UIExceptionNotifier.Notify(ex, "", "Error ");
                }
            }
            get { return _dmRelationship; }
        }

        private void SetupRelatedPropertyColumn()
        {
            BusinessObjectCollection<DMProperty> properties = null;
            if (_dmRelationship != null)
            {
                var relatedClass = _dmRelationship.RelatedClass;
                if (relatedClass != null) properties = relatedClass.AllProperties;
            }
            if (properties == null)
            {
                properties = new BusinessObjectCollection<DMProperty>();
            }
            SetupColumnLookupWithProperties(properties, "ReverseRelationshipProperty.PropertyID");
        }

        private void ReverseRelationship_OnClassPropertyUpdated(object sender, BOPropEventArgs e)
        {
            SetupRelatedPropertyColumn();
        }

        private void SetupOwnerPropertyColumn()
        {
            BusinessObjectCollection<DMProperty> properties = null;
            if (_dmRelationship != null)
            {
                var ownerClass = _dmRelationship.OwnerClass;
                if (ownerClass != null) properties = ownerClass.AllProperties;
            }
            if (properties == null)
            {
                properties = new BusinessObjectCollection<DMProperty>();
            }
            SetupColumnLookupWithProperties(properties, "PropertyID");
        }

        private void SetupColumnLookupWithProperties(BusinessObjectCollection<DMProperty> properties, string columnName)
        {
            ReadOnlyDataSetProvider readOnlyDataSetProvider = new ReadOnlyDataSetProvider(properties);
            IUIGrid uiGrid = ClassDef.Get<DMProperty>().GetUIDef("ComboLookup").UIGrid;
            DataTable dataTable = readOnlyDataSetProvider.GetDataTable(uiGrid);
            IDataGridViewComboBoxColumn column = (IDataGridViewComboBoxColumn) SelectorAndBOEditorControl.Grid.Columns[columnName];
            if (column == null) return;
            column.DataSource = dataTable;
            column.DisplayMember = "PropertyName";
            column.ValueMember = "PropertyID";
        }

        public IBusinessObjectCollection BusinessObjectCollection
        {
            get { return SelectorAndBOEditorControl.BusinessObjectCollection; }
        }

        private void UpdateState()
        {
            this.Enabled = _dmRelationship != null;
            if (_dmRelationship == null || _dmRelationship.Generated.Value)
            {
                EnableGridForEditing(false);
            }
            else
            {
                EnableGridForEditing(true);
            }
        }

        private void EnableGridForEditing(bool enableEditing)
        {
            this.SelectorAndBOEditorControl.AllowUsersToAddBO = enableEditing;
            this.SelectorAndBOEditorControl.AllowUsersToDeleteBO = enableEditing;
            this.SelectorAndBOEditorControl.AllowUsersToEditBO = enableEditing;
        }

        public void SetForm(IFormHabanero form)
        {
        }

        #region Implementation of IBusinessObjectControl

        /// <summary>
        ///             Gets or sets the business object being represented
        /// </summary>
        public IBusinessObject BusinessObject
        {
            get { return this.Relationship; }
            set { this.Relationship = (DMRelationship) value; }
        }

        #endregion
    }
}